package com.fjec.common.config;

import com.fjec.common.Const;
import com.fjec.common.util.IpUtil;
import com.fjec.common.util.SequenceIdGenerator;
import com.fjec.common.zk.ZkDatacenterIdAndWorkerIdHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

@Slf4j
//@Configuration
public class CommonZkConfig {
    /**
     * session timeout
     */
    @Value("${common.zk.sessionTimeoutMs}")
    private int sessionTimeoutMs = 4000;
    /**
     * 链接超时时间
     */
    @Value("${common.zk.connectionTimeoutMs}")
    private int connectionTimeoutMs = 1000;
    /**
     * 最大关闭等待时间
     */
    @Value("${common.zk.maxCloseWaitMs}")
    private int maxCloseWaitMs = 5000;
    /**
     * 试策略，初试时间
     */
    @Value("${common.zk.baseSleepTimeMs}")
    private int baseSleepTimeMs = 3000;
    /**
     * 重试次数
     */
    @Value("${common.zk.maxRetries}")
    private int maxRetries = 5;
    /**
     * 链接地址
     */
    @Value("${common.zk.connectUrl}")
    private String connectUrl;

    @Bean
    public CuratorFramework curator() {
        //重试策略，初试时间1秒，重试10次
        RetryPolicy policy = new ExponentialBackoffRetry(baseSleepTimeMs, maxRetries);
        CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
                .sessionTimeoutMs(sessionTimeoutMs)
                .connectionTimeoutMs(connectionTimeoutMs)
                .maxCloseWaitMs(maxCloseWaitMs)
                .connectString(connectUrl)
                .retryPolicy(policy);
        CuratorFramework curatorFramework = builder.build();
        curatorFramework.start();
        return curatorFramework;
    }

    @Bean
    public ZkDatacenterIdAndWorkerIdHelper zkDatacenterIdAndWorkerIdHelper(CuratorFramework curator) {
        return new ZkDatacenterIdAndWorkerIdHelper(curator);
    }

    @Bean
    public SequenceIdGenerator sequenceIdGenerator(ZkDatacenterIdAndWorkerIdHelper helper) {
        int path = 0;
        try {
            String hostIp = IpUtil.getHostIp();
            helper.createNode(Const.ZK_DATACENTERID_AND_WORKERID_ROOT, hostIp, CreateMode.PERSISTENT);
            path = helper.computeDataCenterAndWorkId(hostIp);
            log.info(String.format("ZK获取[PATH]=%s", path));
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error(ex.getMessage(), ex);
            System.exit(0);
        }
        return new SequenceIdGenerator(path >> 5, path & 0x1F);
    }


}
